import type { RefObject, Dispatch, SetStateAction } from 'react';
import { JSONSchema7 } from 'json-schema';

export interface ApiChannel {
  id: string;
  name: string;
  baseUrl: string;
  apiKey: string;
}

export type ModelPurpose =
  | 'general'
  | 'narrative'
  | 'avatar'
  | 'map'
  | 'hybrid-planning'
  | 'hybrid-narrative'
  | 'hybrid-status';


export interface ModelConfig {
  id: string;
  displayName: string;
  apiModelName: string; // The actual model name the API expects
  apiChannelId: string; // ID of the ApiChannel to use
  temperature: number;
  maxTokens: number;
  purpose?: ModelPurpose; // New: To specify the intended use of the model
}

export enum AiCallMode {
  Single = "single",
  Triple = "triple",
  Double = "double",
  Hybrid = "hybrid",
}

export interface GameSettings {
  apiChannels: ApiChannel[];
  modelConfigs: ModelConfig[];
  defaultTextModelId: string | null;
  // Changed to reflect a general narrative image model, other purposes can be selected specifically
  defaultNarrativeImageModelId: string | null;
  maxHistoryLengthToDisplay: number;
  aiCallMode: AiCallMode;
  alwaysShowManualParseModal: boolean; // New: For debugging AI responses
  corsProxyUrl: string;
  requestTimeout: number; // API request timeout in milliseconds
  hybridModeStreamNarrative?: boolean;
  enableCalculationHelperAi?: boolean; // New: For calculation helper AI mode
  enableFunctionCallingMode?: boolean; // New: For function calling experimental mode
  showCalculationHelperAiPlan?: boolean; // New: For debugging the calculation helper AI plan
  showFunctionCallDebug?: boolean; // New: For debugging function calls
  defaultHybridPlanningModelId?: string | null;
  defaultHybridNarrativeModelId?: string | null;
  defaultHybridStatusModelId?: string | null;
}

export interface Rulebook {
  gameName: string;
  backgroundStory: string;
  rules: string;
}

export interface AiPrompts {
  scenarioGenerationPrompt: string;
  statusPanelPrompt: string;
  keyInfoExtractionPrompt: string;
  functionCallingNarrativePrompt?: string; // New: Dedicated prompt for FC mode
  calculationHelperSystemPrompt?: string;
  narrativeWithCalcsSystemPrompt?: string;
  hybridStructuredDataSystemPrompt?: string;
  toolCallingSystemPrompt?: string;
}

export type AiPromptKey = keyof AiPrompts;


export interface DynamicGameState {
  [key: string]: any;
}

export interface GameTurn {
  id: string; // Unique ID for the turn itself
  imageQuery?: string;
  imageUrl?: string;
  narrative: string;
  options: string[];
  chosenOptionIndex?: number;
  customPlayerInput?: string;
  turnStateSnapshot: DynamicGameState;
  turnKeyInfo: string; // Key info specific to THIS turn
  promptsSentToAi?: {
    calculationHelper?: string;
    narrative?: string;
    structuredData?: string;
    functionCalling?: string;
  };
  functionCallHistory?: { // New: For debugging function calls
    name: string;
    args: Record<string, any>;
    result: string;
  }[];
}

// New enum for macro function scopes
export enum MacroScope {
  Planning = 'planning',
  Narrative = 'narrative',
  Status = 'status',
  Tool = 'tool',
}


// New interface for user-editable macro functions
export interface MacroFunctionParameter {
  name: string;
  description: string;
  // FIX: Added optional type property to align with its usage in gameSaveService.ts
  type?: string;
}

export interface MacroFunction {
  id: string;
  name: string;
  description: string;
  parameters: MacroFunctionParameter[];
  isNative: boolean; // If true, logic is a key to a hardcoded function.
  isEnabled: boolean;
  logic: string; // If native, a key. If not, a formula string.
  outputTemplate: string; // A template for the string output, e.g., "Result: ${result}"
  scopes: MacroScope[]; // New: Defines where the function can be used.
}

export interface ChatMessage {
  role: 'user' | 'assistant';
  content: string;
  // For assistant messages, store the prompt text it generated
  generatedPrompt?: string;
}

export type AiPromptsChatHistory = {
  [key in AiPromptKey]?: ChatMessage[];
};


export interface GameData {
  id: string; // Unique ID for the game save
  rulebook: Rulebook;
  aiPrompts: AiPrompts;
  macroFunctions: MacroFunction[]; // New: User-defined macro functions
  gameHistory: GameTurn[];
  aggregatedKeyInfo: string; // This will be rebuilt from turnKeyInfo entries
  lastPlayedTimestamp: number; // For accurate last played time
  isDefaultTestGame?: boolean; // Flag for the special test game
  originalGameId?: string; // For duplicated games
  aiPromptsChatHistory?: AiPromptsChatHistory; // New: For storing chat history for each prompt
  rulebookChatHistory?: ChatMessage[];
}

export interface SavedGameMeta {
  id: string;
  name: string;
  lastPlayedTimestamp: number;
  isDefaultTestGame?: boolean;
  originalGameId?: string;
}

export enum AppScreen {
  MainMenu,
  CreateGame,
  GameScreen,
  Settings,
}

export interface AiScenarioResponse {
  narrative: string;
  options: string[];
  imageQuery?: string;
}

export interface AiScenarioAndKeyInfoResponse {
  narrative: string;
  options: string[];
  imageQuery?: string;
  keyInfoUpdate: string;
}


// This type might be less relevant now with custom APIs and split calls,
// but keeping it in case some internal structures still benefit.
export interface AiFullResponse {
  scenario: AiScenarioResponse;
  statusPanelContent: DynamicGameState;
  keyInfoUpdate: string;
}

export interface JsonPatchOperation {
  op: 'add' | 'remove' | 'replace';
  path: string; // JSON Pointer path, e.g., "/character/hp"
  value?: any; // Required for 'add' and 'replace'
}

export interface AiHybridStructuredDataResponse {
  options: string[];
  statusPanelPatch: JsonPatchOperation[];
  keyInfoUpdate: string;
  imageQuery?: string;
  function_calls?: { // New: Optional function calls for status updates
    name: string;
    args: Record<string, any>;
  }[];
}

export type TxtExportType = 'narrative' | 'keyInfo' | 'both';

// For Calculation Helper AI Mode
export interface GuidingAiPlan {
  short_prompt: string;
  function_calls: {
    name: string;
    args: Record<string, any>;
  }[];
}

export interface CalculationDebugInfo {
  plan: GuidingAiPlan;
  results: string;
  onContinue: () => void;
}

// For Function Calling Mode
export interface FunctionCallingTurnResponse {
  narrative: string;
  structuredData: AiHybridStructuredDataResponse;
}

// For real-time updates during function calling
export type TurnUpdate =
  | { type: 'task'; content: string }
  | { type: 'function_result'; content: string };

export type TurnUpdateCallback = (update: TurnUpdate) => void;


// --- New Component Prop Interfaces ---

export interface GameHeaderProps {
  gameData: GameData;
  isLoading: boolean;
  currentTurn: GameTurn | undefined;
  onShowRulebook: () => void;
  onShowAiConfig: () => void;
  onShowAiContext: () => void;
  onCopyImageQuery: () => void;
  onConsolidateKeyInfo: () => void;
  onBacktrack: () => void;
  onSaveGame: () => void;
  onExportGame: () => void;
  onExportTxt: () => void;
  onGoToMainMenu: () => void;
  showFunctionCallDebugButton: boolean;
  onShowFunctionCallDebug: () => void;
  onGoToSettings: () => void;
  isHybridMode: boolean;
  isCalculationHelperEnabled: boolean;
  onToggleCalculationHelper: () => void;
}

export interface LeftPanelProps {
  isOpen: boolean;
  width: number;
  currentTurn: GameTurn | undefined;
  currentTurnIndex: number;
  updateDynamicStateField: (turnIndex: number, path: string, value: any) => void;
  changedPaths: Set<string>;
  aiCallMode: AiCallMode;
}

export interface CenterPanelProps {
  isImageLoading: boolean;
  currentAiTask: string | null;
  currentImage: string | null;
  currentTurn: GameTurn | undefined;
  gameHistory: GameTurn[];
  isLoading: boolean;
  customAction: string;
  defaultImageModelExists: boolean;
  // FIX: (Line 271) Changed React.RefObject to RefObject after import.
  mainContentRef: RefObject<HTMLDivElement>;
  setCustomAction: (action: string) => void;
  handleOptionClick: (optionText: string, optionIndex: number) => void;
  handleCustomActionSubmit: () => void;
  updateField: (path: string, value: any, skipSave?: boolean) => void;
}

export interface RightPanelProps {
  isOpen: boolean;
  width: number;
  gameHistory: GameTurn[];
  currentTurnIndex: number;
  handleTurnKeyInfoSave: (turnIndex: number, newKeyInfo: string) => void;
}

export interface GameScreenProps {
  initialGameData: GameData;
  settings: GameSettings;
  setCurrentScreen: (screen: AppScreen) => void;
  showToast: (message: string, type?: 'success' | 'error') => void;
  onSettingsChange: (newSettings: GameSettings) => void;
  onGoToSettings: () => void;
  isGuideActive?: boolean;
  onGuideAdvance?: () => void;
}

export interface AiConfigModalProps {
    isOpen: boolean;
    onClose: () => void;
    gameData: GameData;
    settings: GameSettings;
    editablePrompts: AiPrompts;
    editableMacros: MacroFunction[];
    editableChatHistory: AiPromptsChatHistory;
    // FIX: Replaced React.Dispatch and React.SetStateAction with Dispatch and SetStateAction to fix namespace errors.
    setEditablePrompts: Dispatch<SetStateAction<AiPrompts>>;
    setEditableMacros: Dispatch<SetStateAction<MacroFunction[]>>;
    setEditableChatHistory: Dispatch<SetStateAction<AiPromptsChatHistory>>;
    onSave: () => void;
    onShowHelp: (content: { title: string; content: any }) => void;
    nativeFunctionsDoc: any;
    macroTutorial: any;
    showToast: (message: string, type?: 'success' | 'error') => void;
    isGuideActive?: boolean;
    onGuideAdvance?: () => void;
}